#define INTEGER_NODE 0
#define IDENT_NODE 1
#define AFFECT_NODE 2
#define ADD_NODE 3
#define SUB_NODE 4
#define MUL_NODE 5
#define DIV_NODE 6
#define MOD_NODE 7
#define COMP_NODE 8

/*
	structure noeud d'instruction de l'AST
*/
typedef struct node {
	int type;
	int value;
	struct node* left;
	struct node* optional1;
	struct node* optional2;
	struct node* right;
} node;

/*
	Liste chainée d'instructions 
*/
typedef struct code_block { 
  node* elem;
  struct code_block* next;
} code_block;

void add_node_to_block(code_block* block,node* node){
	if(block == NULL) {
		block = malloc(sizeof(code_block));
		block->elem = node;
	}
	else {
		if(block->next==NULL){
			code_block new;
			new.elem=node;
			block->next=&new;
		}
		else add_node_to_block(block->next,node);
	}
	return;
} 

/*******************************************
 *        Constructeurs de noeuds          *
********************************************/

node* ident_node(char *ident){
	node* n = malloc(sizeof(node));
	n->type = IDENT_NODE;
	n->value = 1; //a replacer par le numéro dans la table des symboles
	return n;
}
node* integer_node(int i){
	node* n = malloc(sizeof(node));
	n->type = INTEGER_NODE;
	n->value = i; 
	return n;
}

node* affect_node(node* ident,node* val){
	node* n = malloc(sizeof(node));
	n->type = AFFECT_NODE;
	n->right = ident;
	n->left = val;
	return n;
}

node* add_node(node* n1,node* n2){
	node* n = malloc(sizeof(node));
	n->type = ADD_NODE;
	n->right = n1;
	n->left = n2;
	return n;
}

node* sub_node(node* n1,node* n2){
	node* n = malloc(sizeof(node));
	n->type = SUB_NODE;
	n->right = n1;
	n->left = n2;
	return n;
}

node* mul_node(node* n1,node* n2){
	node* n = malloc(sizeof(node));
	n->type = MUL_NODE;
	n->right = n1;
	n->left = n2;
	return n;
}

node* div_node(node* n1,node* n2){
	node* n = malloc(sizeof(node));
	n->type = DIV_NODE;
	n->right = n1;
	n->left = n2;
	return n;
}

node* mod_node(node* n1,node* n2){
	node* n = malloc(sizeof(node));
	n->type = MOD_NODE;
	n->right = n1;
	n->left = n2;
	return n;
}

void print_node(int shift,node* node){
	int i=0;
	for(i=0;i<shift;i++)printf("\t");
	switch (node->type) { 
		case INTEGER_NODE :
			printf("%d\n",node->value);
		break;
		case IDENT_NODE :
			printf("%d\n",node->value);
		break;
		case AFFECT_NODE :
			printf("=\n");
		break;
		case ADD_NODE :
			printf("+\n");
		break;
		case SUB_NODE :
			printf("-\n");
		break;

	}
	if(node->right!=NULL)print_node(shift+1,node->right);
	if(node->left!=NULL)print_node(shift+1,node->left);	
}

void print_AST(int shift, code_block* block){
	if(block!=NULL){
		print_node(shift,block->elem);
		print_AST(shift,block->next);
	}
}



